package com.gh.cloud.common.oauth2.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.gh.cloud.commons.core.constant.Oauth2CodeEnum;
import com.gh.cloud.commons.core.utils.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler;
import org.springframework.security.oauth2.provider.expression.OAuth2WebSecurityExpressionHandler;
import org.springframework.security.web.AuthenticationEntryPoint;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @author zlt
 */
@Slf4j
public class DefaultSecurityHandlerConfig {
    @Resource
    private ObjectMapper objectMapper;

    /**
     * 未登录，返回401
     *
     * @return
     */
    @Bean
    public AuthenticationEntryPoint authenticationEntryPoint() {
       return (request, response, e) -> {
           log.warn("oauth2 认证失败，requestUrl={},message={}",request.getRequestURI(),e.getMessage());

           ResponseUtil.responseWriter(objectMapper,response,e.getMessage(), Oauth2CodeEnum.TOKEN_ERROR.getCode());
       };
//        return (request, response, authException) -> ResponseUtil.responseFailed(objectMapper, response, e.getMessage()) ;
    }

    @Bean
    public OAuth2WebSecurityExpressionHandler oAuth2WebSecurityExpressionHandler(ApplicationContext applicationContext) {
        OAuth2WebSecurityExpressionHandler expressionHandler = new OAuth2WebSecurityExpressionHandler();
        expressionHandler.setApplicationContext(applicationContext);
        return expressionHandler;
    }

    /**
     * 处理spring security oauth 处理失败返回消息格式
     */
    @Bean
    public OAuth2AccessDeniedHandler oAuth2AccessDeniedHandler() {
        return new OAuth2AccessDeniedHandler() {

            @Override
            public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException authException) throws IOException, ServletException {
                log.warn("OAuth2AccessDeniedHandler fail，requestUrl={},message={}",request.getRequestURI(),authException.getMessage());

                ResponseUtil.responseFailed(objectMapper, response, authException.getMessage());
            }
        };
    }
}
